package org.mbds.sensorsdatacollector.android.activity;

import java.util.ArrayList;
import java.util.Locale;

import org.mbds.sensorsdatacollector.android.R;
import org.mbds.sensorsdatacollector.android.config.Properties;
import org.mbds.sensorsdatacollector.android.db.SensorData;
import org.mbds.sensorsdatacollector.android.tools.FileUtilities;
import org.mbds.sensorsdatacollector.android.tools.SensorObserverInterface;
import org.mbds.sensorsdatacollector.android.tools.SensorsDataManager;
import org.mbds.sensorsdatacollector.android.activity.MapCompassActivity;


import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;


public class MainActivity extends Activity implements SensorObserverInterface /*, OnItemSelectedListener*/, OnInitListener {
	
	public String selectedActivity;
	private static TextToSpeech tts = null;
//	private static boolean isFist = false;
	// Pour tester en "dur" avec le Samsung Galaxy Note 2 (delay fastest)
	private final static int NB_PEAKS_MAX = 4;
	private final static int NB_PEAKS_MIN = 1;
	private final static float Y_MAX_MAX = 7;
	private final static float Y_MAX_MIN = 0.8f;
	private final static float Y_MAX_MIN_REPOS = -0.5f;
	private final static float Y_MAX_MAX_REPOS = 0.5f;
	
	
	// Pour tester en "dur" avec le Samsung Nexus S (delay fastest)
//	private final static int NB_PEAKS_MAX = 20;
//	private final static int NB_PEAKS_MIN = 8;
//	private final static float Y_MAX_MAX = 10;
//	private final static float Y_MAX_MIN = 1f;
	
	private static boolean isThreadRunning = false;

	@Override
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		WindowManager.LayoutParams params = getWindow().getAttributes();
		params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
		getWindow().setAttributes(params);
		
		tts = new TextToSpeech(getApplicationContext(), this);
		
		Button graphs = (Button) findViewById(R.id.button_graph);

		graphs.setOnClickListener(new View.OnClickListener() {

		    public void onClick(View view) {
		    	try {
		    		Intent graphs_view = new Intent();
		    		graphs_view.setClass(MainActivity.this.getBaseContext(), SensorChartActivity.class);
		    		graphs_view.setAction(Intent.ACTION_VIEW);
		    		graphs_view.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		    		MainActivity.this.getBaseContext().startActivity(graphs_view);
				} catch (Exception e) {
					
				}
		    }

		});		
		Button map = (Button) findViewById(R.id.button_map);

		map.setOnClickListener(new View.OnClickListener() {

		    public void onClick(View view) {
		    	try {
		    		Intent map_view = new Intent();
		    		map_view.setClass(MainActivity.this.getBaseContext(), MapCompassActivity.class);
		    		map_view.setAction(Intent.ACTION_VIEW);
		    		map_view.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		    		MainActivity.this.getBaseContext().startActivity(map_view);
				} catch (Exception e) {
					
				}
		    }

		});		
		
		
		Button Start = (Button) findViewById(R.id.Start_button);

		Start.setOnClickListener(new View.OnClickListener() {

		    public void onClick(View view) {
		    	try {
/*		    		if(myThread==null || myThread.isAlive() ){
		    			myThread = new MyThread();
		    		
		    		}
		    		myThread.start();
*/		    		
		    		Toast.makeText(getApplicationContext(), "Data collection started", Toast.LENGTH_SHORT).show();		    		
		    		startRegistering(view);
		    		//new ProcessSensorData(datas)
		    		
		    		
		    		
				} catch (Exception e) {
					
				}
		    }

		});
		
		final int ok = SensorsDataManager.retrieveDataFromDB();
		
		Button Stop = (Button) findViewById(R.id.Stop_button);

		Stop.setOnClickListener(new View.OnClickListener() {

		    public void onClick(View view) {
		    	try {
/*		    		if(myThread!=null && myThread.isAlive() ){
		    			myThread.stop = true;
		    		
		    		}
*/		    		stopRegistering();
		    		Toast.makeText(getApplicationContext(), "Data collection stopped", Toast.LENGTH_SHORT).show();
		    		Toast.makeText(getApplicationContext(), "Nombre de pics: " + ok , Toast.LENGTH_LONG).show();
		    		
		    		
		    							
				} catch (Throwable e) {
					e.printStackTrace();
				}
		    }

		});
		
		
		//final TextView tv = (TextView) findViewById(R.id.print_y);
		
		final EditText tv = (EditText) findViewById(R.id.print_val_y);
		Button Print = (Button) findViewById(R.id.Y_button);

		Print.setOnClickListener(new View.OnClickListener() {

		    public void onClick(View view) {
		    	
		    			 try {
		    				/* for (int i = 0; i<SensorsDataManager.y_val.size();i++){
		    						tv.append("\n" + SensorsDataManager.y_val.get(i));*/
		    				 for (int i = 0; i<SensorsDataManager.y_val.size();i++){
		    						tv.append("\n" + SensorsDataManager.y_val.get(i));
		    					}
		    						
						} catch (Exception e) {
							// TODO Auto-generated catch block
							//e.printStackTrace();
						}   		
		    							
				
		    }

		});
				
	}
	
	
	@Override
	public void onResume(){
		super.onResume();
		//Creation a spinner list that displays data from each sensor type.
		final Spinner Delay_list = (Spinner)findViewById(R.id.sensors_data_view); // Get the spinner that will displays the list of sensors on the device.
		//Create an adapter to get the list of items to be displayed in the spinner box.
		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.Delay_list, android.R.layout.simple_spinner_item);
		
		//Specifying the layout to be used when the spinner box list of choices appears.
		
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
		
		//Finally populate the spinner with list of items to be displayed.
		Delay_list.setAdapter(adapter);
		
		//Listen to the list selection 
		//String nameActivity;
		
		//nameActivity= Activity_list.getSelectedItem().toString();
		 //nameActivity =  Activity_list.getSelectedItem().toString();
		// Toast.makeText(getApplicationContext(),nameActivity , Toast.LENGTH_SHORT).show();	
		 
		
		      
		Delay_list.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
		                        public void onItemSelected(
		                                AdapterView<?> adapterView, View view,
		                                int i, long l ) {
		                        	
		                    		try {
		                    			stopRegistering();
		                    		} catch (Throwable e) {
		                    			e.printStackTrace();
		                    		}
		                        	selectedActivity = Delay_list.getItemAtPosition(i).toString();
		                        	Toast.makeText(getApplicationContext(),selectedActivity , Toast.LENGTH_SHORT).show();
		                        }

		                        public void onNothingSelected(
		                                AdapterView<?> adapterView) {

		                        }
		                    });
		   
		
		 
		 
		selectedActivity = Delay_list.getItemAtPosition(0).toString();
		 
		
		 //Activity_list.setOnItemSelectedListener(this); 
		
//		isFist = false;
	}	
	
	/*
	 * The 2 following methods are called when either start or stop button are pressed in this respectively
	 */
	public void startRegistering(View v){
		//SensorsDataManager.magneticFieldData.addObserver(this);
		SensorsDataManager.accelerometerData.addObserver(this);
		/*SensorsDataManager.gyroscopeData.addObserver(this);
		SensorsDataManager.rotationData.addObserver(this);
		SensorsDataManager.linearAccelData.addObserver(this);
		SensorsDataManager.gravityData.addObserver(this);
		SensorsDataManager.pressureData.addObserver(this);
		SensorsDataManager.proximityData.addObserver(this);*/
		
		// Start collect data
		//SensorsDataManager.magneticFieldData.startDataCollection(selectedActivity);
		SensorsDataManager.accelerometerData.startDataCollection(selectedActivity);
		/*SensorsDataManager.gyroscopeData.startDataCollection(selectedActivity);
		SensorsDataManager.rotationData.startDataCollection(selectedActivity);
		SensorsDataManager.linearAccelData.startDataCollection(selectedActivity);
		SensorsDataManager.gravityData.startDataCollection(selectedActivity);
		SensorsDataManager.pressureData.startDataCollection(selectedActivity);
		SensorsDataManager.proximityData.startDataCollection(selectedActivity);*/
	}
	
	public void stopRegistering() throws Throwable{
		// Stop collect data
		//SensorsDataManager.magneticFieldData.stopDataCollection();
		SensorsDataManager.accelerometerData.stopDataCollection();
		/*SensorsDataManager.gyroscopeData.stopDataCollection();
		SensorsDataManager.rotationData.stopDataCollection();
		SensorsDataManager.linearAccelData.stopDataCollection();
		SensorsDataManager.gravityData.stopDataCollection();
		SensorsDataManager.pressureData.stopDataCollection();
		SensorsDataManager.proximityData.stopDataCollection();*/
		//SensorsDataManager.magneticFieldData.removeObserver(this);
		SensorsDataManager.accelerometerData.removeObserver(this);
		/*SensorsDataManager.gyroscopeData.removeObserver(this);
		SensorsDataManager.rotationData.removeObserver(this);
		SensorsDataManager.linearAccelData.removeObserver(this);
		SensorsDataManager.gravityData.removeObserver(this);
		SensorsDataManager.pressureData.removeObserver(this);
		SensorsDataManager.proximityData.removeObserver(this);*/
	}
	

	public void stopDataCollection() {
	}
	
	@Override
	public void finish() {
		try {
			stopRegistering();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	// Is these method used ?
//	public void onItemSelected(AdapterView<?> parent, View view, int position,
//			long rowID) {
//		if(isFist){
//			String content = Properties.PATH+parent.getItemAtPosition(position).toString();
//			Intent displaySensorData = new Intent(Intent.ACTION_DEFAULT);
//			//displaySensorData.setAction(Intent.ACTION_VIEW); // We want to view the content of a file.
//			//displaySensorData.addCategory(Intent.CATEGORY_DEFAULT);
//			//displaySensorData.addCategory(Intent.CATEGORY_BROWSABLE);
//			displaySensorData.setType("text/csv");
//			displaySensorData.setData(Uri.fromFile(new File(content)));
//			startActivity(displaySensorData);
//		}else{
//			isFist = true;
//		}
//	}


//	public void onNothingSelected(AdapterView<?> arg0) {
//		// TODO Auto-generated method stub
//		
//	}


	public void updateSensorData(ArrayList<SensorData> datas,
			double lastDeltaTime, SensorData lastValues) {
		// Run within a Thread the data recognition 
		if (!isThreadRunning) {
			ProcessSensorData p = new ProcessSensorData(datas);
		}
	}
	
	/**
	 * Thread to analyse every 1 second the data from sensors
	
	 *
	 */
	
	class ProcessSensorData extends Thread {
		ArrayList<SensorData> data;

		public ProcessSensorData(ArrayList<SensorData> datas) {
			if (!isThreadRunning) {
				setThreadRunning(true);
				this.data = datas;
				start();
			}
		}	
		
		public void run() {

			float val_n = 9999;
			float val_nPlus1 = 9999;
			float
			val_nMoins1 = 0;
			ArrayList<Float> peaks = new ArrayList<Float>();
			boolean ok_marche = true;
			boolean ok_course = false;	
			boolean ok_secouer = false;
			boolean ok_repos = false;
			String debug = "";
			int size = data.size();
			
			if (size>0) {
				float[] values = new float[size];
				synchronized (values) {
					// Get peaks values
					for (int i = 0; i<size;i++) {
						SensorData s = data.get(i);
						synchronized(s) {
							float val=s.val[1];
							debug+=val+";";
							values[i]=val;
						}
					}
					for (int x = 0; x<size;x++) {
						val_nMoins1=val_n;
						val_n = values[x];
	
						if (x<size-1) {
							val_nPlus1=values[x+1];
							System.out.println("VAL_Nmoins1: " + val_nMoins1 + " VAL_N: " + val_n + " VAL_nPLUS1: " +val_nPlus1);
							if (val_nPlus1<val_n && val_n>val_nMoins1) {
								peaks.add(val_n);
							}
						}
					}
					
					System.out.println("NBRES de Peaks: " + peaks.size());
					System.out.println("Data : "+debug);
					
					// Check if user is walking or running
					if (peaks.size()<=NB_PEAKS_MAX && peaks.size()>=NB_PEAKS_MIN) {
						for (int n=0; n<peaks.size();n++) {
							float val = peaks.get(n);
							if (val>Y_MAX_MAX-1)
								ok_course=true;
							if (val<Y_MAX_MIN || val>Y_MAX_MAX) {
								ok_marche = false;
							}
						}
					} else {
						ok_marche = false;
					}
					if (ok_marche) {
		//				final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
		//			     tg.startTone(ToneGenerator.TONE_PROP_BEEP);
						if (ok_course)
							textToSpeech("run", "RUN");
						else
							textToSpeech("walk", "WALK");
					} else {
						// Check other activities
						
						// Check mobile shake
						ok_secouer = false;
						for (int n=0; n<size;n++) {
							if (values[n]>Y_MAX_MAX)
								ok_secouer= true;
						}
						if (ok_secouer) {
		//					final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
		//				     tg.startTone(ToneGenerator.TONE_PROP_BEEP);		
							textToSpeech("Shake", "SHAKE");
						} else {
							// Check mobile sleep
							ok_repos = false;
							if (size== 0) {
								ok_repos = true;				 
							} else { 
								ok_repos = true;				 
								for (int n=0; n<size;n++) {
									float val = values[n];
									if (val<Y_MAX_MIN_REPOS || val>Y_MAX_MAX_REPOS)
										ok_repos = false;
								}
							}
							if (ok_repos) {
		//						final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
		//					     tg.startTone(ToneGenerator.TONE_PROP_BEEP);		
								textToSpeech("Sleep", "SLEEP");
							}
						}
					}
				}
				setThreadRunning(false);
			}
		}
	}

	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			quit();
			return true;
		}
		return false;
	}
	public void quit() {
		finish();
		android.os.Process.killProcess(android.os.Process.myPid());
		java.lang.System.exit(0);
	}

	/**
	 * Convert text to speech
	 * @param text
	 * @return
	 */
	public static boolean textToSpeech(String message, String title) {
		boolean res = false;
		if (tts!=null) {
			res = tts.speak(message, TextToSpeech.QUEUE_FLUSH, null)==0;
		}
		return res;
	}

	public void onInit(int status) {
		if (status == TextToSpeech.SUCCESS) {
			tts.setLanguage(Locale.ENGLISH);
		}
	}
	
	public static boolean isThreadRunning() {
		return isThreadRunning;
	}


	public static void setThreadRunning(boolean isThreadRunning) {
		MainActivity.isThreadRunning = isThreadRunning;
	}

//	private MyThread myThread;
//	private class MyThread extends Thread{
//		public boolean stop;
//		
//		@Override
//		public void run() {
//			try {
//				// TODO Auto-generated method stub
//							
//				while(!stop){
//					sleep(3000);
//					Message msg = mThreadHandler.obtainMessage(MSG_WHAT_MESSAGE);
//					//msg.what = MSG_WHAT_MESSAGE;
//					Bundle data = new Bundle();
//					data.putString(BUNDLE_MESSAGE, "Je suis au thread");
//					data.putString(BUNDLE_TITLE, "Titre");
//					
//					msg.setData(data);
//					
//					mThreadHandler.handleMessage(msg);
//					Log.i("ThreadTag","je suis au thread");
//				}
//			} catch (Exception e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//			
//		}
//
//	}
//	
//	public static final String BUNDLE_MESSAGE = "message";
//	public static final String BUNDLE_TITLE = "title";
//	public static final int MSG_WHAT_MESSAGE = 1;
//	
//	private Handler mThreadHandler = new Handler(){
//		@Override
//		public void handleMessage(Message msg) {
//			// TODO Auto-generated method stub
//			//super.handleMessage(msg);
//			
//			switch (msg.what) {
//				case MSG_WHAT_MESSAGE:
//					Toast.makeText(MainActivity.this, msg.getData().getString(BUNDLE_MESSAGE), Toast.LENGTH_LONG).show();
//					break;
//
//				default:
//					break;
//			}
//			
//			
//		}
//	};

}
